import numpy as np
import pandas as pd
import dalex as dx
import pickle
housing = pd.read_csv('housing_preprocessed.csv')
# xgb = pickle.load(open("xgb.pickle", 'rb'))
gb = pickle.load(open("gradient_boost.pickle", 'rb'))
housing.head()
| longitude | latitude | housing_median_age | total_bedrooms | population | households | median_income | <1H OCEAN | INLAND | NEAR BAY | NEAR OCEAN | rooms_per_household | median_house_value | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.211155 | 0.567481 | 0.784314 | 0.019711 | 0.008941 | 0.020395 | 0.539668 | 0.0 | 0.0 | 1.0 | 0.0 | 0.046610 | 452600.0 |
| 1 | 0.212151 | 0.565356 | 0.392157 | 0.171349 | 0.067210 | 0.186842 | 0.538027 | 0.0 | 0.0 | 1.0 | 0.0 | 0.040945 | 358500.0 |
| 2 | 0.210159 | 0.564293 | 1.000000 | 0.029179 | 0.013818 | 0.028783 | 0.466028 | 0.0 | 0.0 | 1.0 | 0.0 | 0.056513 | 352100.0 |
| 3 | 0.209163 | 0.564293 | 1.000000 | 0.036163 | 0.015555 | 0.035691 | 0.354699 | 0.0 | 0.0 | 1.0 | 0.0 | 0.037750 | 341300.0 |
| 4 | 0.209163 | 0.564293 | 1.000000 | 0.043148 | 0.015752 | 0.042270 | 0.230776 | 0.0 | 0.0 | 1.0 | 0.0 | 0.041277 | 342200.0 |
predictors = housing.drop('median_house_value', axis = 1)
target = housing.loc[:, ['median_house_value']]
observation = predictors.loc[[420], :]
gb.predict(observation)
array([386498.09536054])
explainer = dx.Explainer(gb, predictors, target)
Preparation of a new explainer is initiated -> data : 19643 rows 12 cols -> target variable : Parameter 'y' was a pandas.DataFrame. Converted to a numpy.ndarray. -> target variable : 19643 values -> model_class : sklearn.ensemble._gb.GradientBoostingRegressor (default) -> label : Not specified, model's class short name will be used. (default) -> predict function : <function yhat_default at 0x0000029B4C177E50> will be used (default) -> predict function : Accepts pandas.DataFrame and numpy.ndarray. -> predicted values : min = 1.59e+04, mean = 1.92e+05, max = 5.08e+05 -> model type : regression will be used (default) -> residual function : difference between y and yhat (default) -> residuals : min = -2.62e+05, mean = -1.2e+02, max = 2.8e+05 -> model_info : package sklearn A new explainer has been created!
ps = explainer.predict_surrogate(observation, type = "lime")
ps.show_in_notebook()
Ta nieruchomość została oceniona wysoko. Największy wkład miały informacja o medianie zarobków, położeniu geograficznym oraz fakt, że nieruchomość nie jest w głębi lądu (INLAND = 0).
observation2 = predictors.loc[1024]
observation3 = predictors.loc[34]
observation4 = predictors.loc[2021]
observation5 = predictors.loc[2137]
ps2 = explainer.predict_surrogate(observation2, type = "lime")
ps3 = explainer.predict_surrogate(observation3, type = "lime")
ps4 = explainer.predict_surrogate(observation4, type = "lime")
ps5 = explainer.predict_surrogate(observation5, type = "lime")
ps2.show_in_notebook()
ps3.show_in_notebook()
ps4.show_in_notebook()
ps5.show_in_notebook()
Real estatate is about location, location. location. We wszystkich rozważanych obserwacjach za istotne są zmienne latitude, longitude oraz opisujące położenie względem oceanu (INLAND, NEAR BAY etc.). Te zmienne są często istotne i mają podobny wpływ wśród wybranych obserwacji.
Pozostałe zmienne zachowują się różnie. Część z nich jest tylko czasami istotna (median_income, rooms_per_household, total_bedrooms, ...). Tym niemniej, wśród wybranych obserwacji podobne wartości zmiennych mają podobny wkład - nie zauważyłem sytuacji, gdzie zmienna miałaby raz wkład dodatni, raz ujemny.
Wydaje się, że ta metoda jest bardziej stablina (reliable) od metody BreakDown. Czytelnie tłumaczy pojedyncze predykcje i pozwala na częściowe zrozumienie modelu.